package se.webbzon.boltzmann.effect;

import java.util.ArrayList;

import javax.media.j3d.Transform3D;
import javax.vecmath.Vector3d;

import se.webbzon.boltzmann.resource.Resources;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;
import se.webbzon.oschi01.worldobject.appearance.CylinderAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.GroupAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.SimpleAppearance3D;

public class EarthquakeEffect extends WorldStaticObject implements Effect {
	
	// The start y-position of the effect
	private final double yStart;
	
	// The magnitude of the earthquake shock wave
	private final double magnitude;
	
	// The startup duration of the effect
	private final int duration;

	// The remaining duration of the effect
	private int remaining;
	
	/*============================================================
	Constructors
	============================================================*/

	public EarthquakeEffect(WorldStaticObject parent, double magnitude, int duration) {
		super(WorldObject.onStep, createAppearance());
		setPosition(parent.getX(),parent.getY() - parent.getHeight()/2,parent.getZ());
		this.magnitude = magnitude;
		this.duration = duration;
		yStart = getY();
		remaining = duration;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public void onStep(WorldArea world) {
		if (remaining == 0)
			terminate(world);
		else if (remaining > 0) {
			remaining--;
			final double t = 8 - (8 * remaining) / (double) duration;
			setRotation(0,1,0,Math.PI * t);
			final double height = magnitude * t * Math.exp(-t);
			final double radius = t * magnitude;
			setSize(radius, height, radius);
			setPosition(getX(),yStart + height/2,getZ());
		}
	}

	@Override public void launch(WorldArea world) {
		world.createInstance(this);
	}

	@Override public void terminate(WorldArea world) {
		world.destroyInstance(this);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	private static final Appearance3D createAppearance() {
		ArrayList<Appearance3D> appearances = new ArrayList<Appearance3D>();
		
		SimpleAppearance3D front = new CylinderAppearance3D(true);
		front.setTextureSet(Resources.getTextureSet("terrain_road_road_01"));
		appearances.add(front);
		
		SimpleAppearance3D back = new CylinderAppearance3D(true);
		back.setTextureSet(Resources.getTextureSet("terrain_road_road_01"));
		Transform3D transform = new Transform3D();
		transform.setScale(new Vector3d(1,1,-1));
		back.setTransform(transform);
		appearances.add(back);
		
		return new GroupAppearance3D(appearances);
	}

}
